//============================================================================
// Name        : MyExProj.cpp
// Author      : karthik
// Version     :
// Copyright   : Your copyright notice
// Description : Main file for Multi-factor Option Pricing.
//============================================================================

#include <iostream>
#include <sstream>
#include <vector>
#include <time.h>

#include "Date.h"
#include "Option.h"
#include "OptionPricer.h"
#include "Portfolio.h"
#include "normal.h"
#include "Utils.h"
#include "ConfigFile.h"
#include "Statistics.h"
#include "mtrand.h"
#include "halton.h"

#include "tnt_jama/tnt.h"
#include "tnt_jama/jama_cholesky.h"

using namespace std;
using namespace JAMA;  // JAMA and TNT are defined in namespaces.
using namespace TNT;  // without the "using" statement we would have to write JAMA:: or TNT::
// in front of the functions or fields we are using

typedef vector< vector<double> > VofV;
typedef vector< vector<string> > csvVector;

int main() {

	ConfigFile config("input_config.txt");
	//	cout<<"Reading config file."<<endl;

	double rate = config.read<double>("rate");
	double strike = config.read<double>("strike");
	int trials = config.read<int>("trials");

	cout<<"No of trials to be run :"<<trials<<endl;

	csvVector csvData;
	Statistics::readCSV("open_prices.csv", csvData);

	VofV prices;	// 10*44 vector.

	int historical_days = csvData.size()-1;
	int n = csvData[0].size()-1;	//	no of stocks.

	//	cout<<"h_days,n: "<<historical_days<<", "<<n<<endl;
	for (int i=1;i<=n;i++){	// for each stock
		vector<double> col;
		for (int j=1;j<=historical_days;j++){	// for each historical day
			double x=fromString<double>(csvData[j][i]);
			col.push_back(x);
		}
		prices.push_back(col);
	}

	VofV returns;	// 10*43 vector.
	returns = Statistics::pricesToReturns(prices);

	vector<double> vols ;
	vector<double> mean_returns ;
	vector<double> starting_prices;

	for (int i=0;i<n;i++){
		vols.push_back(Statistics::annualVolatility<double>(returns[i]));
		mean_returns.push_back(Statistics::mean<double>(returns[2]));
		starting_prices.push_back(prices[i][historical_days-1]);
	}

	cout << "\nVols :" <<endl;
	printVofDouble(vols);
	//	printVofDouble(mean_returns);


	Array2D<double> stockCorrMatrix = Statistics::CorrelationMatrix<double>(returns);

	Date exp_date = Date(18,12,9);
	Date present_date = Date(30,10,9);

	Option opt("S&P-10", exp_date, strike, true);
	OptionPricer opt_pricer(opt ,starting_prices,rate,vols,stockCorrMatrix);	// option has strike,expiration

	double val;

	time_t rawtime;
	struct tm * timeinfo;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	printf ( "Current local time and date: %s", asctime (timeinfo) );


	val= opt_pricer.price("Mersenne",trials,present_date);		//	Run by MonteCarlo Method using Mersenne Twister random no generation
	cout<<"Option Price as determined by OptionPricer (Mersenne): "<<val<<endl;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	printf ( "Current local time and date: %s", asctime (timeinfo) );

	val= opt_pricer.price("Halton",trials,present_date);		//	Run by MonteCarlo Method using Halton random no generation
	cout<<"\nOption Price as determined by OptionPricer(Halton)   : "<<val<<endl;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	printf ( "Current local time and date: %s", asctime (timeinfo) );

	cout<<"Done;"<<endl;

	return 0;
}

